<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

<script>
    var zhang = {
        name: "张三",
        age: 18,
        height: "177cm",
        weight: "70kg",
    }
    console.log(zhang);

    // 如何删除对象的属性?  => 借助delete关键词
    // delete zhang.height;
    // delete zhang.weight;
    // console.log(zhang);


    // 如何定义对象的属性?   => 定义对象的属性值,是否可写,是否可枚举,是否可删除
    // (1) 传统的定义对象的属性  => 点语法/中括号语法  (没有就新增,有就修改)  => 没有任何限制(属性可改写 可以被遍历 可以被删除)
    // zhang.height = "180cm";
    // zhang["weight"] = "80kg";
    // console.log(zhang);

    // delete zhang.height;
    // delete zhang.weight;
    // console.log(zhang);

    // (2) 自定义对象的属性 (构造函数Object的方法 => 构造函数自己用)
    // Object.defineProperty()         定义对象的属性(一次一个)
    // Object.defineProperties()       定义对象的属性(一次多个)
    // Object.getOwnPropertyDescriptor()  获取对象的属性描述(一次一个)
    // Object.getOwnPropertyDescriptors()  获取对象的属性描述(一次多个)

    // Object.defineProperty(target,key,options)
    // target  目标对象(定义属性的对象)
    // key     定义的属性名
    // options 对属性的修饰(对象)
    //     value: 值
    //     writable: 是否可以改写(默认:false)
    //     enumerable: 是否可以枚举(被循环遍历)  (默认:false)
    //     configable:  是否可以删除  (默认:false)

    /* var zhang = {};
    Object.defineProperty(zhang, "name", {
        value: "李四",
        writable: false,
        enumerable: false,
        configurable: false,
    })

    Object.defineProperty(zhang, "age", {
        value: 25,
        writable: false,
        enumerable: false,
        configurable: false,
    })

    zhang.name = "王五";
    for (var key in zhang) {
        console.log("key:", key);
    }
    delete zhang.name;

    console.log(zhang); */


    // Object.defineProperties(target,desc)
    // target  目标对象(定义属性的对象)
    // desc     定义的属性描述  {key:options,key:options,key:options}

    // options 对属性的修饰(对象)
    //     value: 值
    //     writable: 是否可以改写(默认:false)
    //     enumerable: 是否可以枚举(被循环遍历)  (默认:false)
    //     configable:  是否可以删除  (默认:false)
    var zhang = {};
    Object.defineProperties(zhang, {
        name: {
            value: "张三",
            writable: false,
            enumerable: false,
            configurable: false,
        },
        age: {
            value: 25,
            writable: false,
            enumerable: false,
            configurable: false,
        },
        height: {
            value: "175cm",
            writable: false,
            enumerable: false,
            configurable: false,
        },
        weight: {
            value: "70kg",
            writable: false,
            enumerable: false,
            configurable: false,
        }
    })

    zhang.name = "王五";
    for (var key in zhang) {
        console.log("key:", key);
    }
    delete zhang.name;

    console.log(zhang);


    // 获取对象的属性描述
    // Object.getOwnPropertyDescriptor(target, key)
    // console.log(Object.getOwnPropertyDescriptor(zhang, "name"));
    // console.log(Object.getOwnPropertyDescriptor(zhang, "age"));
    // console.log(Object.getOwnPropertyDescriptor(zhang, "height"));
    // console.log(Object.getOwnPropertyDescriptor(zhang, "weight"));

    // Object.getOwnPropertyDescriptors(target)
    // console.log(Object.getOwnPropertyDescriptors(zhang));


    // 字符串可以下标取值 ,但是不能下标赋值  => 所有字符串的方法都不会影响原字符串 => 如果需要返回内容 只能返回新字符串
    var str = new String("hello");
    str[4] = "O";
    console.log(str);
    console.log(Object.getOwnPropertyDescriptors(str))






</script>

</html>